package cn.stylefeng.mferp.modular.business.service.impl;

import cn.stylefeng.mferp.core.common.constant.DatasourceEnum;
import cn.stylefeng.mferp.modular.business.model.Trwdphbycl;
import cn.stylefeng.mferp.modular.business.dao.TrwdphbyclMapper;
import cn.stylefeng.mferp.modular.business.model.TrwdphbyclModel;
import cn.stylefeng.mferp.modular.business.service.ITrwdphbyclService;
import cn.stylefeng.roses.core.mutidatasource.annotion.DataSource;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.Collator;
import java.util.*;

/**
 * <p>
 * 任务单施工配比原材料 服务实现类
 * </p>
 *
 * @author yzr
 * @since 2020-05-27
 */
@Service
public class TrwdphbyclServiceImpl extends ServiceImpl<TrwdphbyclMapper, Trwdphbycl> implements ITrwdphbyclService {

    @Autowired
    private TrwdphbyclMapper trwdphbyclMapper;

    /**
     * 查询该任务单的所有配比信息
     *
     * @param rwdh
     * @param scbt
     * @return
     */
    @DataSource(name = DatasourceEnum.DATA_SOURCE_BIZ)
    @Override
    public List<TrwdphbyclModel> getTrwdphbYclListByFrwdh(String rwdh, String scbt) {
        List<TrwdphbyclModel> list = trwdphbyclMapper.getTrwdphbYclListByFrwdh(rwdh, scbt);
        list = TrwdphbyclModel.sortByPzgg(list);
        return list;
    }

    /**
     * 单个配合比原材料信息调整掺量
     *
     * @param ycls
     * @param cl
     * @return
     */
    @Override
    public List<TrwdphbyclModel> adjustCl(List<TrwdphbyclModel> ycls, double cl) {
        if(ycls == null || ycls.isEmpty()) return ycls;
        if(new BigDecimal(Double.toString(cl)).compareTo(BigDecimal.ZERO) == 0) return ycls;
        // 总胶材用量                    // 总外加剂用量        // 原有掺量    // 新掺量
        BigDecimal pow = BigDecimal.ZERO, ad = BigDecimal.ZERO,     ocl,    ncl;
        // fid与sysl的关联
        Map<Integer, BigDecimal> map = new HashMap<>();
        // 计算总胶材、总外加剂用量、记录外加剂fid
        for(TrwdphbyclModel ym : ycls) {
            Integer id = ym.getFid();
            String ylmc  = ym.getFylmc();
            String pzgg = ym.getFpzgg();
            Double p = ym.getFsysl();
            if((ylmc.contains("水泥") || ylmc.contains("粉煤灰") || ylmc.contains("矿粉")) && p != null) {
                pow = pow.add(new BigDecimal(Double.toString(p)));
            } else if(ylmc.contains("外加剂") && !pzgg.contains("B1") && p != null) {
                ad = ad.add(new BigDecimal(Double.toString(p)));
                map.put(id, new BigDecimal(Double.toString(p)));
            }
        }
        // 总胶材小于等于零，则不更新
        if(pow.compareTo(BigDecimal.ZERO) <= 0) {
            return ycls;
        }
        ocl = ad.multiply(new BigDecimal(100)).divide(pow, 2, RoundingMode.HALF_UP);
        ncl = ocl.add(new BigDecimal(Double.toString(cl)));
        //不能大于5个掺量，不能小于1个掺量
        if(ncl.compareTo(new BigDecimal(5)) > 0 || ncl.compareTo(new BigDecimal(1)) < 0) return ycls;
        for(TrwdphbyclModel ym : ycls) {
            if(map.containsKey(ym.getFid())) {
                BigDecimal a = new BigDecimal(Double.toString(ym.getFsysl()));
                //新掺量 = 旧掺量 + 差值
                //新外加剂用量/ （总胶材 * 新掺量 / 100） = 原外加剂用量/原外加剂总用量
                BigDecimal v = pow.multiply(ncl).divide(new BigDecimal(100)).multiply(a).divide(ad, 2, RoundingMode.HALF_UP);
                ym.setFsysl(v.doubleValue());
            }
        }
        return ycls;
    }

    /**
     * 单个配合比原材料信息调整砂率
     *
     * @param ycls 配合比原材料列表
     * @param sl   砂率
     * @return 返回调整完毕的配合比原材料列表
     */
    @Override
    public List<TrwdphbyclModel> adjustSl(List<TrwdphbyclModel> ycls, double sl) {
        if(ycls == null || ycls.isEmpty()) return ycls;
        if(new BigDecimal(Double.toString(sl)).compareTo(BigDecimal.ZERO) == 0) return ycls;
        // 总骨料用量
        BigDecimal aggregate;
        // 总砂用量
        BigDecimal sand = BigDecimal.ZERO;
        // 总石用量
        BigDecimal stone = BigDecimal.ZERO;
        // 新总砂用量
        BigDecimal sandNew = BigDecimal.ZERO;
        // 新总石用量
        BigDecimal stoneNew = BigDecimal.ZERO;
        // 原有砂率
        BigDecimal originSl;
        // 新砂率
        BigDecimal newSl;
        // fid与sysl的关联
        Map<Integer, BigDecimal> map1 = new HashMap<>();
        Map<Integer, BigDecimal> map2 = new HashMap<>();
        for(TrwdphbyclModel ym : ycls) {
            Integer id = ym.getFid();
            String ylmc  = ym.getFylmc();
            Double p = ym.getFsysl();
            if((ylmc.contains("石") || ylmc.contains("瓜米")) && p != null) {
                stone = stone.add(new BigDecimal(Double.toString(p)));
                map1.put(id, new BigDecimal(Double.toString(p)));
            } else if(ylmc.contains("砂") && p != null) {
                sand = sand.add(new BigDecimal(Double.toString(p)));
                map2.put(id, new BigDecimal(Double.toString(p)));
            }
        }
        // 总骨料小于等于零，则不更新
        aggregate = stone.add(sand);
        if(aggregate.compareTo(BigDecimal.ZERO) <= 0) {
            return ycls;
        }
        originSl = sand.multiply(new BigDecimal(100)).divide(aggregate, 1, RoundingMode.HALF_UP);
        newSl = originSl.add(new BigDecimal(Double.toString(sl)));
        //不能大于55个砂率，不能小于25个砂率
        if(newSl.compareTo(new BigDecimal(55)) > 0 || newSl.compareTo(new BigDecimal(25)) < 0) return ycls;
        for(TrwdphbyclModel ym : ycls) {
            //调砂
            if(map2.containsKey(ym.getFid())) {
                BigDecimal a = new BigDecimal(Double.toString(ym.getFsysl()));
                //原总骨料 = 新总骨料 骨料保持不变、砂占比保持不变
                //砂1/原总砂 = 新砂1/（总骨料*新砂率/100）
                //（总骨料*新砂率/100）*砂1/原总砂 = 新砂1
                BigDecimal v = aggregate.multiply(newSl).divide(new BigDecimal(100)).multiply(a).divide(sand, 3, RoundingMode.UP).divide(new BigDecimal(5), 0, RoundingMode.HALF_UP).multiply(new BigDecimal(5));
                sandNew = sandNew.add(v);
                ym.setFsysl(v.doubleValue());
            }
            //调石
            if(map1.containsKey(ym.getFid())) {
                BigDecimal a = new BigDecimal(Double.toString(ym.getFsysl()));
                BigDecimal v = aggregate.multiply(new BigDecimal(100).subtract(newSl)).divide(new BigDecimal(100)).multiply(a).divide(stone, 3, RoundingMode.UP).divide(new BigDecimal(5), 0, RoundingMode.HALF_UP).multiply(new BigDecimal(5));
                ym.setFsysl(v.doubleValue());
                stoneNew = stoneNew.add(v);
            }
        }
        //扣除差值
        BigDecimal difference = sandNew.add(stoneNew).subtract(aggregate);
        if(difference.compareTo(BigDecimal.ZERO) > 0) {
            for (TrwdphbyclModel ym : ycls) {
                if (map1.containsKey(ym.getFid())) {
                    BigDecimal a = new BigDecimal(Double.toString(ym.getFsysl()));
                    BigDecimal v = a.subtract(difference);
                    ym.setFsysl(v.doubleValue());
                    break;
                }
            }
        }
        return ycls;
    }
}
